package com.zhu.tool_test.starke.framework.redis.event;




import com.zhu.tool_test.starke.framework.redis.annotations.EventHandler;
import com.zhu.tool_test.starke.framework.redis.annotations.QueueEvent;
import com.zhu.tool_test.starke.matrix.multipart.core.Data;
import com.zhu.tool_test.starke.matrix.multipart.core.MultipartData;
import com.zhu.tool_test.starke.util.lang.Strings;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author  4everlynn
 * @version V1.0
 * @description 事件收集器 单例
 * @date 2019-04-16
 */
public class EventCollector {
    private static MultipartData data = new MultipartData();
    private static EventCollector collector = new EventCollector();
    private static final String MODULE_NAME = "all-modules";

    private EventCollector() {
    }

    public static EventCollector instance() {
        return collector;
    }

    /**
     * 获得事件的所有响应方法
     *
     * @param moduleName 事件模块
     * @return EventMethodInvoker
     */
    public List<EventMethodInvoker> getEventHandler(String moduleName, String eventName) {
        if (null == moduleName) {
            return new ArrayList<>();
        }
        // 获得模块名称
        MultipartData part = data.getPart(moduleName, MultipartData.class);
        if (null != part) {
            return part.getListPart(eventName, EventMethodInvoker.class);
        }
        return new ArrayList<>();
    }

    /**
     * 获得所有的事件处理
     *
     * @return 获得所有的事件处理
     */
    public Data events() {
        return data;
    }

    /**
     * 采集事件
     *
     * @param eventName 事件名称
     * @param bean      执行事件处理的对象
     * @param method    方法
     */
    public void collect(String eventName, Object bean, Method method) {
        // 必须参数带齐才会采集
        if (method == null || bean == null) {
            return;
        }
        EventMethodInvoker invoker = new EventMethodInvoker();
        invoker.setMethod(method);
        invoker.setRunner(bean);
        String moduleName;
        QueueEvent queueEvent = method.getDeclaredAnnotation(QueueEvent.class);
        // 优先判断方法上的注解
        if (!MODULE_NAME.equals(queueEvent.moduleName())) {
            moduleName = queueEvent.moduleName();
        } else {
            EventHandler eventHandler
                    = bean.getClass().getDeclaredAnnotation(EventHandler.class);
            if (!Strings.isNullOrEmpty(eventHandler.moduleName())) {
                moduleName = eventHandler.moduleName();
            } else {
                moduleName = MODULE_NAME;
            }
        }
        data.putIfAbsent(moduleName, new MultipartData());
        MultipartData part = data.getPart(moduleName, MultipartData.class);
        part.putIfAbsent(eventName, new ArrayList<EventMethodInvoker>());
        List<EventMethodInvoker> listPart = part.getListPart(eventName, EventMethodInvoker.class);
        listPart.add(invoker);
    }
}
